﻿using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;

/// <summary>
///XMLManipulation 的摘要说明
/// </summary>
public class XMLManipulation
{
    private static XmlDocument xDoc = new XmlDocument();

    public static EditResult WriteToConfig(string filePath, string xPath, ConfigNode cn)
    {
        if (GetConfig(filePath, xPath).Count >= 10)
        {
            return EditResult.MoreThenTen;
        }
        if (IsExsited(filePath, xPath, cn))
        {
            return EditResult.Duplicated;
        }
        xDoc.Load(filePath);
        XmlNode xn = xDoc.SelectSingleNode(xPath);
        XmlElement newNode = xDoc.CreateElement("pic");
        XmlAttribute prdtId = xDoc.CreateAttribute("Id");
        prdtId.Value = cn.Id.ToString();
        newNode.Attributes.Append(prdtId);
        XmlAttribute prdtName = xDoc.CreateAttribute("name");
        prdtName.Value = cn.Name;
        newNode.Attributes.Append(prdtName);
        XmlAttribute imgSrc = xDoc.CreateAttribute("src");
        imgSrc.Value = cn.Src;
        newNode.Attributes.Append(imgSrc);
        XmlAttribute prdtDescrip = xDoc.CreateAttribute("description");
        prdtDescrip.Value = cn.Description;
        newNode.Attributes.Append(prdtDescrip);
        xn.AppendChild(newNode);
        try
        {
            xDoc.Save(filePath);
            return EditResult.Success;
        }
        catch (Exception)
        {
            return EditResult.Fail;
        }
    }

    private static bool IsExsited(string filePath, string xPath, ConfigNode cn)
    {
        xDoc.Load(filePath);
        XmlNode xnl = xDoc.SelectSingleNode(xPath);
        foreach (XmlNode xn in xnl.ChildNodes)
        {
            if (xn.Attributes["Id"].Value == cn.Id.ToString())
            {
                return true;
            }
        }
        return false;
    }

    public static List<ConfigNode> GetConfig(string filePath, string xPath)
    {
        List<ConfigNode> cnList = new List<ConfigNode>();
        ConfigNode cn;

        xDoc.Load(filePath);
        XmlNode xnl = xDoc.SelectSingleNode(xPath);
        foreach (XmlNode xn in xnl.ChildNodes)
        {
            cn = new ConfigNode();
            cn.Id = Convert.ToInt32(xn.Attributes["Id"].Value);
            cn.Name = xn.Attributes["name"].Value;
            cn.Src = xn.Attributes["src"].Value;
            cn.Description = xn.Attributes["description"].Value;
            cnList.Add(cn);
        }
        return cnList;
    }

    public static bool DelNode(string filePath, string xPath)
    {
        try
        {
            xDoc.Load(filePath);
            XmlNode xn = xDoc.SelectSingleNode(xPath);
            XmlNode xnParent = xn.ParentNode;
            xnParent.RemoveChild(xn);
            xDoc.Save(filePath);
            return true;
        }
        catch
        {
            return false;
        }
    }
    public static XmlNodeList GetNodes(string filePath, string xPath)
    {
        try
        {
            xDoc.Load(filePath);
            XmlNodeList xnl = xDoc.SelectNodes(xPath);
            return xnl;
        }
        catch
        {
            return null;
        }        
    }

    public static bool UpdateNodes(string filePath, string xPath, List<ConfigNode> cnList)
    {
        try
        {
            xDoc.Load(filePath);
            foreach (ConfigNode cn in cnList)
            {
                XmlNode xn = xDoc.SelectSingleNode(xPath);
                xn.Attributes["Id"].Value = cn.Id.ToString();
                xn.Attributes["name"].Value = cn.Name;
                xn.Attributes["src"].Value = cn.Src;
                xn.Attributes["price"].Value = cn.Price.ToString();
                xn.Attributes["marketPrice"].Value = cn.PriceMarket.ToString();
                xn.Attributes["description"].Value = cn.Description;
            }
            xDoc.Save(filePath);
            return true;
        }
        catch
        {
            return false;
            throw;
        }
    }
}

public enum EditResult { MoreThenTen = 0, Success, Fail, Duplicated };

public class ConfigNode
{
    private int id;
    private string name;
    private decimal marketPrice;
    private decimal price;
    private string src;
    private string description;

    public ConfigNode()
    { }

    public ConfigNode(int id, string name, string src, string description)
    {
        this.id = id;
        this.name = name;
        this.src = src;
        this.description = description;
    }

    public ConfigNode(int id, string name, decimal marketPrice, decimal price, string src, string description)
    {
        this.id = id;
        this.name = name;
        this.marketPrice = marketPrice;
        this.price = price;
        this.src = src;
        this.description = description;
    }
    public virtual int Id
    {
        get { return id; }
        set { id = value; }
    }

    public virtual string Name
    {
        get { return name; }
        set { name = value; }
    }
    public virtual decimal PriceMarket
    {
        get { return marketPrice; }
        set { marketPrice = value; }
    }

    public virtual decimal Price
    {
        get { return price; }
        set { price = value; }
    }
    public virtual string Src
    {
        get { return src; }
        set { src = value; }
    }
    public virtual string Description
    {
        get { return description; }
        set { description = value; }
    }
}

#region XML temp
//private static void CreateNodeForXMLFile(PersonProfile pp)
//{
//    XmlElement newPerson = xDoc.CreateElement("Person");//new element
//    newPerson.SetAttribute("Name", pp.PName);

//    XmlElement pSex = xDoc.CreateElement("Sex");
//    pSex.InnerText = pp.PSex;
//    newPerson.AppendChild(pSex);//add the new element as the sub-element of "Person"
//    XmlElement pPhone = xDoc.CreateElement("Phone");
//    pPhone.InnerText = pp.PPhone;
//    newPerson.AppendChild(pPhone);
//    XmlElement pBirth = xDoc.CreateElement("Birthday");
//    pBirth.InnerText = pp.PBirth;
//    newPerson.AppendChild(pBirth);
//    XmlElement pCompany = xDoc.CreateElement("Company");
//    pCompany.InnerText = pp.PCompany;
//    newPerson.AppendChild(pCompany);
//    XmlElement pPhotoPath = xDoc.CreateElement("Photo");
//    pPhotoPath.InnerText = pp.PPhotoPath;
//    newPerson.AppendChild(pPhotoPath);
//    XmlElement pHomeAddr = xDoc.CreateElement("HomeAddr");
//    pHomeAddr.InnerText = pp.PHomeAddr;
//    newPerson.AppendChild(pHomeAddr);
//    XmlElement pUniversity = xDoc.CreateElement("University");
//    pUniversity.InnerText = pp.PUniversity;
//    newPerson.AppendChild(pUniversity);
//    xDoc.DocumentElement.AppendChild(newPerson);//insert the new element into the root element
//}
//private static void NewFile(string fileName)
//{
//    XmlDeclaration newDec = xDoc.CreateXmlDeclaration("1.0", null, null);
//    xDoc.AppendChild(newDec);
//    XmlElement newRoot = xDoc.CreateElement("PersonProfile");
//    xDoc.AppendChild(newRoot);
//    WriteToFile(fileName);
//}
//public static bool EditXMLFile(ConfigNode conNode)
//{
//    XmlNodeList xnl = GetNodeList(null, null, conNode.PName, TypeOfNodeName.Attribute);
//    int i = 1;
//    foreach (XmlNode xn in xnl)
//    {
//        xn.Attributes["Name"].Value = conNode[0];
//        XmlNodeList xnlSub = xn.ChildNodes;
//        foreach (XmlNode xnSub in xnlSub)
//        {
//            xnSub.InnerText = conNode[i++];
//        }
//    }
//    //When complete read the data out of the file, and make modification, you can save it by this sentences.
//    xDoc.Save(filePath);
//    return true;
//}
/// <summary>
/// Get Node list
/// </summary>
/// <param name="xPath">xPath expression,nullable.Default element xpath://Person/nodeName;Default attribute xpath://Person[@Name='nodeValue']</param>
/// <param name="nodeName">For element name,not null.For attribute name,nullable.Default attribute name:Name</param>
/// <param name="nodeValue">For attribute value,not null.No node value for element</param>
/// <param name="typeOfNodeName">For both,type of nodename, not null</param>
/// <returns></returns>
//public static XmlNodeList GetNodeList(string xPath, string nodeName, string nodeValue, TypeOfNodeName typeOfNodeName)
//{
//    //XmlDocument xDoc = new XmlDocument();
//    xDoc.Load(filePath);
//    XmlNode root = xDoc.DocumentElement;
//    XmlNodeList xnl = null;
//    if (typeOfNodeName == TypeOfNodeName.Attribute)
//    {
//        if (xPath != null)
//        {
//            xnl = root.SelectNodes(xPath + "[@" + nodeName + "='" + nodeValue + "']");//注意属性Key的大小写
//        }
//        xnl = root.SelectNodes("//Person[@Name='" + nodeValue + "']");//注意属性Key的大小写
//    }
//    if (typeOfNodeName == TypeOfNodeName.Element)
//    {
//        if (xPath != null)
//        {
//            xnl = root.SelectNodes(xPath + "/'" + nodeName + "'");
//        }
//        xnl = root.SelectNodes("//Person/'" + nodeName + "'");
//    }
//    return xnl;
//}
#endregion